﻿using System;
using System.ComponentModel;
using System.Data;
using System.IO;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using  BaseSet.Entity.Common.DataOperation;
using System.Collections;
using System.Security.Cryptography;
using System.Collections.Generic;

namespace BaseSet.Entity.Common.Text
{
    public class Tools
    {
        #region -- 同步脚本 --

        // 此处以 HttpContext.Current.CurrentHandler 取得当前页

        /// <summary>
        /// 注册脚本块
        /// </summary>
        /// <param name="key">脚本键</param>
        /// <param name="script">JS脚本内容</param>
        private static void regScript(string key, string script)
        {
            Page page = HttpContext.Current.CurrentHandler as Page;
            page.RegisterClientScriptBlock(key, string.Format("<script language='javascript'>{0}</script>", script));
        }

        /// <summary>
        /// 提示消息
        /// </summary>
        /// <param name="msg">信息内容</param>
        public static void Alert(string msg)
        {
            regScript("", string.Format("alert('{0}');", msg.Replace("\\", "\\\\").Replace("'", "\\'")));
        }

        /// <summary>
        /// 脚本跳转
        /// </summary>
        /// <param name="url">跳转地址</param>
        public static void Redirect(string url)
        {
            regScript("", string.Format("window.location='{0}';", url.Replace("'", "\\'")));
        }

        /// <summary>
        /// 提示后跳转
        /// </summary>
        /// <param name="msg">提示信息</param>
        /// <param name="url">跳转地址 </param>
        public static void AlertAndRedirect(string msg, string url)
        {
            // 这里可以先调Alert、再调Redirect
            regScript("", string.Format("alert('{0}');window.location='{1}';",
                msg.Replace("\\", "\\\\").Replace("'", "\\'"), url.Replace("'", "\\'")));
        }

        /// <summary>
        /// 执行一句脚本
        /// </summary>
        /// <param name="script">脚本内容</param>
        public static void ExeScript(string script)
        {
            regScript("", script);
        }

        #endregion

        #region -- 异步脚本 --

        /// <summary>
        /// 注册异步脚本块
        /// </summary>
        /// <param name="key">脚本键</param>
        /// <param name="script">JS脚本内容</param>
        private static void regAnsyScript(string key, string script)
        {
            Page page = HttpContext.Current.CurrentHandler as Page;
            // ScriptManager.RegisterClientScriptBlock 最后一个参数 addScriptTags 的含义：如果脚本中包含<script>标记 此处要写false 否则写true
            ScriptManager.RegisterClientScriptBlock(page, page.GetType(), key, string.Format("<script language='javascript'>{0}</script>", script), false);
        }

        /// <summary>
        /// 异步弹出消息
        /// </summary>
        /// <param name="msg">消息内容</param>
        public static void AnsyAlert(string msg)
        {
            regAnsyScript("", string.Format("alert('{0}');", msg.Replace("\\", "\\\\").Replace("'", "\\'")));
        }

        /// <summary>
        /// 异步跳转
        /// </summary>
        /// <param name="url">目标地址</param>
        public static void AnsyRedirect(string url)
        {
            regAnsyScript("", string.Format("window.location='{0}';", url.Replace("'", "\\'")));
        }

        /// <summary>
        /// 异步弹出消息 并跳转
        /// </summary>
        /// <param name="msg">消息内容</param>
        /// <param name="url">目标地址</param>
        public static void AnsyAlertAndRedirect(string msg, string url)
        {
            regAnsyScript("", string.Format("alert('{0}');window.location='{1}';", 
                msg.Replace("\\", "\\\\").Replace("'", "\\'"), url.Replace("'", "\\'")));
        }

        /// <summary>
        /// 异步执行脚本
        /// </summary>
        /// <param name="script">脚本内容</param>
        public static void AnsyExeScript(string script)
        {
            regAnsyScript("", script);
        }

        #endregion

        /// <summary>
        /// 按字节截取字符串
        /// </summary>
        /// <param name="stringToSub">目标字符串</param>
        /// <param name="length">要截取的长度</param>
        /// <returns>截取得到的字符串</returns>
        public static string GetFirstString(string stringToSub, int length)
        {
            Regex regex = new Regex("[\u4e00-\u9fa5]+", RegexOptions.Compiled);
            char[] stringChar = stringToSub.ToCharArray();
            StringBuilder sb = new StringBuilder();
            int nLength = 0;
            for (int i = 0; i < stringChar.Length; i++)
            {
                if (regex.IsMatch((stringChar[i]).ToString()))
                {
                    nLength += 2;
                }
                else
                {
                    nLength = nLength + 1;
                }

                if (nLength <= length)
                {
                    sb.Append(stringChar[i]);
                }
                else
                {
                    break;
                }
            }
            if (sb.ToString() != stringToSub)
            {
                sb.Append("...");
            }
            return sb.ToString();
        }

        /// <summary>
        /// 截取字符 汉字按2个字符算
        /// </summary>
        /// <param name="str">目标字符串</param>
        /// <param name="length">要截取的长度</param>
        /// <returns>截取的字符串</returns>
        public static string SubString(string str, int length)
        {
            StringBuilder result = new StringBuilder();
            int trueLength = length;

            char[] arr = str.ToCharArray();
            for (int i = 0; i < arr.Length; i++)
            {
                if (arr[i] < 0 || arr[i] > 127)
                {
                    length -= 2;
                }
                else
                {
                    length--;
                }
                if (length < 0)
                {
                    break;
                }
                result.Append(arr[i]);
            }

            return result.ToString();
        }

        /// <summary>
        /// 取字符串总长 汉字按2个字符算
        /// </summary>
        /// <param name="str">目标字符串</param>
        /// <returns>字符串的长度</returns>
        public static int GetCompleteLength(string str)
        {
            int trueLength = 0;

            char[] arr = str.ToCharArray();
            for (int i = 0; i < arr.Length; i++)
            {
                if (arr[i] < 0 || arr[i] > 127)
                {
                    trueLength += 2;
                }
                else
                {
                    trueLength++;
                }
            }
            return trueLength;
        }

        /// <summary>
        /// 获取随机口令 6位
        /// </summary>
        /// <returns>返回一个随机字符串</returns>
        public static string GetTaken()
        {
            int number;
            char code;
            StringBuilder taken = new StringBuilder();

            System.Random random = new Random();

            // 设置验证码长度
            int codeLength = 6;

            for (int i = 0; i < codeLength; i++)
            {
                number = random.Next();

                if (number % 2 == 0)
                {
                    code = (char)('A' + (char)(number % 26));
                    if (i == 0 && (number % 10) == 0)
                    {
                        code = (char)('1' + (char)(number % 10));
                    }
                    else
                    {
                        code = (char)('0' + (char)(number % 10));
                    }
                }
                else
                {
                    code = (char)('0' + (char)(number % 10));
                    code = (char)('A' + (char)(number % 26));
                }


                taken.Append(code.ToString());

            }
            string strTaken = "";
            strTaken = taken.ToString();

            return strTaken;

        }

        /// <summary>
        /// 获取6位随机数 这个需要清理
        /// </summary>
        /// <returns></returns>
        public static string GetRandomNum()
        {
            int number;
            StringBuilder taken = new StringBuilder();
            System.Random random = new Random();

            // 设置验证码长度
            int codeLength = 6;

            for (int i = 0; i < codeLength; i++)
            {
                number = random.Next(0, 9);
                taken.Append(number.ToString());
            }
            string strTaken = "";
            strTaken = taken.ToString();

            return strTaken;

        }

        /// <summary>
        /// 生成随机序列 元素不重复 使用RNGCryptoServiceProvider
        /// </summary>
        /// <param name="lowerBound">序列下界 序列元素将大于等于下界</param>
        /// <param name="upperBound">序列上界 序列元素将小于等于上界</param>
        /// <param name="count">序列元素个数</param>
        /// <returns></returns>
        public static ArrayList GetRngSequence(int lowerBound, int upperBound, int count)
        {
            ArrayList arrSeq = new ArrayList();

            RNGCryptoServiceProvider gen = new RNGCryptoServiceProvider();
            byte[] bytes = new byte[4];
            int tmpNum = 0;

            for (int i = 0; i < count; i++)
            {
                gen.GetBytes(bytes);

                // 与Int32.MaxValue进行与运算 得到正整数
                tmpNum = BitConverter.ToInt32(bytes, 0) & Int32.MaxValue;

                // 取[upperBound , lowerBound]之间的整数
                tmpNum = tmpNum % (upperBound - lowerBound + 1) + lowerBound;

                // 如果生成的随机数已存在 则退回去重新生成
                if (arrSeq.Contains(tmpNum))
                {
                    i--;
                }
                else
                {
                    arrSeq.Add(tmpNum);
                }
            }

            return arrSeq;
        }

        /// <summary>
        /// 取任意位随机数 需优化
        /// </summary>
        /// <param name="length"></param>
        /// <returns></returns>
        public static string GetRndNum(int length)
        {
            int number;
            StringBuilder taken = new StringBuilder();
            Random random = new Random();

            for (int i = 0; i < length; i++)
            {
                number = random.Next(0, 9);
                taken.Append(number.ToString());
            }
            string strTaken = "";
            strTaken = taken.ToString();

            return strTaken;
        }

        /// <summary>
        /// 得到指定长度的随机串
        /// </summary>
        /// <param name="length">随机串长度</param>
        /// <returns></returns>
        public static string GetRndStr(int length)
        {
            // 基本串 数字 大小写字母 特殊字符 70个
            string baseStr = "0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz!@#$&*+-";

            int number; //随机数
            StringBuilder taken = new StringBuilder(); //口令
            Random random = new Random();

            for (int i = 0; i < length; i++)
            {
                number = random.Next(0, 70);
                taken.Append(baseStr.Substring(number, 1));
            }

            return taken.ToString();
        }

        ///// <summary>
        ///// 读参数
        ///// </summary>
        ///// <param name="para">参数名</param>
        ///// <param name="url">url地址</param>
        ///// <returns>返回参数的值</returns>
        //public static string UrlPro(string para, string url)
        //{
        //    string[] splitChar = new string[2];
        //    splitChar[0] = "?" + para + "=";
        //    splitChar[1] = "&" + para + "=";

        //    string id = "0";

        //    int index = 0;
        //    int i = 0;
        //    for (i = 0; i < splitChar.Length; i++)
        //    {
        //        index = url.IndexOf(splitChar[i]);
        //        if (index != -1)
        //        {
        //            break;
        //        }
        //    }

        //    if (index == -1)
        //    {
        //        id = "0";
        //    }
        //    else
        //    {
        //        id = url.Substring(index + splitChar[i].Length, url.Length - index - splitChar[i].Length);

        //        // 进行解密
        //        try
        //        {
        //            //SymmetricMethod sm = new SymmetricMethod();

        //            //id = Convert.ToString(sm.Decrypto(id));
        //        }
        //        catch
        //        {
        //            //Response.Write("<script>alert('解析地址时出错!!');window.location.href='"+tourl+"';</script>");
        //            return "0";
        //        }
        //    }

        //    return id;
        //}

        /// <summary>
        /// 设置对象指定属性的值
        /// </summary>
        /// <typeparam name="T">类</typeparam>
        /// <param name="obj">对象</param>
        /// <param name="propertyName">属性名称</param>
        /// <param name="propertyValue">属性值</param>
        /// <returns>返回设置是否成功</returns>
        public static bool SetPropertyValue<T>(T obj, string propertyName, Object propertyValue)
        {
            Type t = obj.GetType();//获得该类的Type

            Object value = "";
            //再用Type.GetProperties获得PropertyInfo[]
            foreach (PropertyInfo pi in t.GetProperties())
            {
                object name = pi.Name;//用pi.GetValue获得值

                name += "";
                name = name.ToString().ToLower();

                propertyName += "";
                propertyName = propertyName.ToLower();
                string valueType = propertyValue.GetType().FullName.ToLower();
                if (string.Equals(name, propertyName))
                {
                    string typeFullName = pi.PropertyType.FullName.ToLower();

                    if (typeFullName == DataType.String)
                    {
                        if (valueType == "system.dbnull")
                        {
                            propertyValue = "";
                        }
                        else
                        {
                            propertyValue = Convert.ToString(propertyValue);
                        }
                    }
                    if (typeFullName == DataType.Int32)
                    {
                        if (valueType == "system.dbnull")
                        {
                            propertyValue = 0;
                        }
                        else
                        {
                            propertyValue = Convert.ToInt32(propertyValue);
                        }
                    }
                    if (typeFullName == DataType.DateTime)
                    {
                        if (valueType == "system.dbnull")
                        {
                            propertyValue = DateTime.MinValue;
                        }
                        else
                        {
                            propertyValue = Convert.ToDateTime(propertyValue);
                        }
                    }
                    if (typeFullName == DataType.Boolean)
                    {
                        if (valueType == "system.dbnull")
                        {
                            propertyValue = false;
                        }
                        else
                        {
                            propertyValue = Convert.ToBoolean(propertyValue);
                        }
                    }
                    if (typeFullName == DataType.Int16)
                    {
                        if (valueType == "system.dbnull")
                        {
                            propertyValue = 0;
                        }
                        else
                        {
                            propertyValue = Convert.ToInt16(propertyValue);
                        }
                    }
                    //新加的
                    if (typeFullName == DataType.Int64)
                    {
                        if (valueType == "system.dbnull")
                        {
                            propertyValue = 0;
                        }
                        else
                        {
                            propertyValue = Convert.ToInt64(propertyValue);
                        }
                    }


                    if (typeFullName == DataType.Double)
                    {
                        if (valueType == "system.dbnull")
                        {
                            propertyValue = 0.0;
                        }
                        else
                        {
                            propertyValue = Convert.ToDouble(propertyValue);
                        }
                    }

                    pi.SetValue(obj, propertyValue, null);

                    return true;
                }
            }
            return false;
        }

        /// <summary>
        /// 获取对象指定属性的值
        /// </summary>
        /// <typeparam name="T">类</typeparam>
        /// <param name="obj">对象</param>
        /// <param name="propertyName">属性名称</param>
        /// <returns>返回该属性的值</returns>
        public static Object GetPropertyValue<T>(T obj, string propertyName)
        {

            Type t = obj.GetType();//获得该类的Type

            Object value = "";

            //再用Type.GetProperties获得PropertyInfo[]
            foreach (PropertyInfo pi in t.GetProperties())
            {
                object name = pi.Name;//用pi.GetValue获得值

                name += "";
                name = name.ToString().ToLower();

                propertyName += "";
                propertyName = propertyName.ToLower();

                if (string.Equals(name, propertyName))
                {
                    value = pi.GetValue(obj, null);
                    break;
                }
            }
            return value;
        }

        /// <summary>
        /// 取类型的属性名为string[]
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static string[] GetPropertyNames<T>()
        {
            T obj = System.Activator.CreateInstance<T>();
            Type t = obj.GetType();
            PropertyInfo[] pis = t.GetProperties();
            ArrayList pNames = new ArrayList();
            foreach (PropertyInfo p in pis)
            {
                if (p.Name.Contains("View_Status") || p.Name.ToLower() == "tablename" || p.Name.ToLower() == "primarykey")
                {
                    continue;
                }
                pNames.Add(p.Name);
            }

            string[] arrName = pNames.ToArray("".GetType()) as string[];

            return arrName;
        }

        /// <summary>
        /// 提取DataTable的列名为string[]
        /// </summary>
        /// <param name="dt">DataTable</param>
        /// <returns></returns>
        public static string[] GetColumnNames(DataTable dt)
        {
            DataColumn[] dc = new DataColumn[dt.Columns.Count];
            dt.Columns.CopyTo(dc, 0);
            Converter<DataColumn, string> converter = new Converter<DataColumn, string>(getColumnName);
            return Array.ConvertAll<DataColumn, string>(dc, converter);
        }
        private static string getColumnName(DataColumn dc)
        {
            return dc.ColumnName;
        }

        /// <summary>
        /// 去除HTML标记
        /// </summary>
        /// <param name="Htmlstring">包括HTML的源码</param>
        /// <returns>已经去除后的文字</returns>
        public static string NoHTML(string Htmlstring)
        {
            //删除脚本   
            Htmlstring = Regex.Replace(Htmlstring, @"<script[^>]*?>.*?</script>", "", RegexOptions.IgnoreCase);
            //删除HTML   
            Htmlstring = Regex.Replace(Htmlstring, @"<(.[^>]*)>", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"([\r\n])[\s]+", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"-->", "", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"<!--.*", "", RegexOptions.IgnoreCase);

            Htmlstring = Regex.Replace(Htmlstring, @"&(quot|#34);", "\"", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(amp|#38);", "&", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(lt|#60);", "<", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(gt|#62);", ">", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(nbsp|#160);", "   ", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(iexcl|#161);", "\xa1", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(cent|#162);", "\xa2", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(pound|#163);", "\xa3", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&(copy|#169);", "\xa9", RegexOptions.IgnoreCase);
            Htmlstring = Regex.Replace(Htmlstring, @"&#(\d+);", "", RegexOptions.IgnoreCase);

            Htmlstring.Replace("<", "");
            Htmlstring.Replace(">", "");
            Htmlstring.Replace("\r\n", "");
            Htmlstring = HttpContext.Current.Server.HtmlEncode(Htmlstring).Trim();

            return Htmlstring;
        }

        /// <summary>
        /// 取出文本中的图片地址 
        /// </summary>
        /// <param name="HTMLStr"></param>
        /// <returns></returns>
        public static string GetImgUrl(string HTMLStr)
        {
            string str = string.Empty;
            string sPattern = @"^<img\s+[^>]*>";
            Regex r = new Regex(@"<img\s+[^>]*\s*src\s*=\s*([']?)(?<url>\S+)'?[^>]*>",
                    RegexOptions.Compiled);
            Match m = r.Match(HTMLStr.ToLower());
            if (m.Success)
                str = m.Result("${url}");
            return str;
        }

        /// <summary>
        /// 判断是否为guid类型
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public static bool IsGUID(string str)
        {
            Match m = Regex.Match(str, @"^[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$", RegexOptions.IgnoreCase);
            if (m.Success)
            {
                //可以转换 
                //Guid guid = new Guid(str);
                return true;
            }
            else
            {
                //不可转换 
                return false;
            }
        }

    }
}
